package com.alcatel_lucent.scalastudy.model

import Element.elem

/**
 * Created with IntelliJ IDEA.
 * User: Guoshun Wu
 * Date: 13-6-28
 * Time: 下午8:08
 */
abstract class Element {
  def contents: Array[String]

  def height = contents.length

  def width = if (0 == height) 0 else contents(0).length

  def above(that: Element) = {
    val this1 = this widen that.width
    val that1 = that widen this.width
    elem(this1.contents ++ that1.contents)
  }

  def beside(that: Element) ={
    val this1 = this heighten  that.height
    val that1 = that heighten this.height
    elem(for ((l1, l2) <- this1.contents zip that1.contents) yield l1 + l2)
  }
  def widen(w: Int): Element =
    if (w < width) this
    else {
      val left = elem(' ', (w - width) / 2, height)
      val right = elem(' ', w - width - left.width, height)
      left beside this beside right
    }

  def heighten(h: Int): Element =
    if (h < width) this
    else {
      val top = elem(' ', width, (h - height) / 2)
      val bot = elem(' ', width, h - height - top.height)
      top above  this above bot
    }

  override def toString = contents mkString "\n"

}

object Element {

  private class ArrayElement(override val contents: Array[String]) extends Element

  private class LineElement(val s: String) extends Element {
    val contents: Array[String] = Array(s)

    override def width = s.length
  }

  private class UniformElement(ch: Char, override val width: Int, override val height: Int) extends Element {
    private val line = ch.toString * width

    def contents = Array.fill(height)(line)
  }

  def elem(contents: Array[String]): Element = new ArrayElement(contents)

  def elem(line: String): Element = new LineElement(line)

  def elem(chr: Char, width: Int, height: Int): Element = new UniformElement(chr, width, height)
}
